//
//  NetworkCenter.m
//  LingQianZhu
//
//  Created by xieyingze on 2016/12/16.
//  Copyright © 2016年 谢英泽. All rights reserved.
//

#import "NetworkCenter.h"
#import "AppHeader.h"
#import "NetworkParam+Center.h"
#import "URLDefine.h"
#import "BaseTabBarController.h"
#import "HUDTool.h"
#import "UnityTool.h"
#import "AppDelegate.h"
#import "DDLoadingView.h"
#import "DDAlertView.h"
#import "DDRegAndLogController.h"

@interface NetworkCenter ()<NSURLConnectionDataDelegate> {
    //获取网络时间相关
    NSURLConnection *_connection;
    void(^_netWorkTimeBlock)(NSTimeInterval timestamp);
    //是否强制更新
    BOOL _isForce;
    /**  强制登出 */
    BOOL _isForceLoginOut;
}
/**
 *  当前版本号
 */
@property (nonatomic, copy) NSString *currentVersion;

@property (nonatomic, copy) NSString *currentSever;

@property (nonatomic, strong) DDLoadingView *loadingView;

@property (nonatomic, copy) NSString *requestMethod;;

@end

@implementation NetworkCenter

#pragma mark - 单例

+ (instancetype)shareInstance {
    static dispatch_once_t once;
    static id _instance;
    dispatch_once(&once, ^{
        _instance = [[self alloc] init];
    });
    return  _instance;
}

/**
 实例初始化
 @return 实例化对象
 */
- (instancetype)init {
    self = [super init];
    if (self) {
        //获取本地版本号
        NSDictionary *infoPlist  = [[NSBundle mainBundle] infoDictionary];
        self.currentVersion         = [infoPlist objectForKey:@"CFBundleShortVersionString"];
        
#if DEBUG
        //测试环境
        NSArray *servers         = @[
//                                     @"http://192.168.3.10:8080/" //家
//                                     @"http://192.168.1.211/ssm/"
                                     @"http://192.168.1.249:8080/"   //公司
                                     ];
        self.currentSever = servers[0];
#else
        //正式环境
        NSArray *servers             = @[
                                         @"http://192.168.3.10:8080/"
                                         ];
        self.currentSever = servers[0];
#endif
    }
    return self;
}

#pragma mark - Block请求方式

- (void)networkRequestWithNetworkParam:(NetworkParam *)networkParam completed:(NetworkCompleted)completed {
    if (networkParam == nil){
        completed(NO,nil);
        return;
    }
    self.requestMethod = networkParam.methodName;
    //添加公共参数
    NSMutableArray *totalArr = [NSMutableArray arrayWithArray:networkParam.paramArr];
    [totalArr addObjectsFromArray:[self commonParameters]];
    networkParam.paramArr = totalArr;
    NSMutableDictionary *totalDict = [[NSMutableDictionary alloc]init];
    
    for (NSDictionary *dict in networkParam.paramArr) {
        [totalDict addEntriesFromDictionary:dict];
    }
#warning 验签
    //NSString *signStr = [self signStringWithParam:totalDict];;
    //测试不用验签
    //[totalDict setObject:[UnityTool md5ForString:signStr] forKey:@"sign"];
    
    networkParam.param = totalDict;
    //全局采用post请求
    networkParam.isPOST = YES;
    
    //networkParam.key = [self keyWithNetworkParam:networkParam];//顺序为：先添加公共参数，再设置key值
    
    if (![self isConnectNetWork]) {
        completed(NO,kREMINDER_noNetwork);
        return ;
    }
    
    //状态栏菊花开启
    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
    if (networkParam.isSHowLoading) {
        [self.loadingView showLoading];
    }
    
    AFHTTPSessionManager *afManager = [AFHTTPSessionManager manager];
    afManager.requestSerializer     = [AFHTTPRequestSerializer serializer];
    afManager.responseSerializer    = [AFHTTPResponseSerializer serializer];
    afManager.requestSerializer.timeoutInterval = 5;
    
    NSString *currentServer = self.currentSever;
    NSString *URLString = kURL_APPEND_URL(currentServer, networkParam.methodName);
    URLString = [URLString stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    
    
    if (networkParam.imgData && networkParam.imgData.length) {
        //上传图片
        [afManager POST:URLString parameters:networkParam.param constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
            //拼接图片
            [formData appendPartWithFileData:networkParam.imgData name:@"pic" fileName:@"pic.jpg" mimeType:@"image/jpg"];
        } progress:^(NSProgress * _Nonnull uploadProgress) {
            
        } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
            [self handleSucessBlockResponseObject:responseObject networkParam:networkParam completed:completed];
        } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
            [self handleFailtureError:error networkParam:networkParam currentServer:currentServer completed:completed];
        }];
        return;
    }
    
    //开始网络请求
    if (networkParam.isPOST) {
        [afManager POST:URLString parameters:networkParam.param progress:nil
                success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                    [self handleSucessBlockResponseObject:responseObject networkParam:networkParam completed:completed];
                }
                failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                    [self handleFailtureError:error networkParam:networkParam currentServer:currentServer completed:completed];
                }
         ];
    } else {
        [afManager GET:URLString parameters:networkParam.param progress:nil
               success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
                   [self handleSucessBlockResponseObject:responseObject networkParam:networkParam completed:completed];
               }
               failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
                   [self handleFailtureError:error networkParam:networkParam currentServer:currentServer completed:completed];
               }
         ];
    }
}

#pragma mark - Block数据处理

- (void)handleSucessBlockResponseObject:(id)responseObject networkParam:(NetworkParam *)networkParam completed:(NetworkCompleted)completed {
    WeakSelf;
    //状态栏菊花关闭
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    if (networkParam.isSHowLoading) {
         [self.loadingView hideLoading];
    }
    //处理后台坑爹的空格Json字符串
    NSMutableString *resultStr = [[NSMutableString alloc] initWithData:responseObject encoding:NSUTF8StringEncoding];
    if (resultStr && resultStr.length>0) {
        NSRange range = [resultStr rangeOfString:@"{"];
        if (range.location != NSNotFound) {
            [resultStr deleteCharactersInRange:NSMakeRange(0, range.location)];
        }
    }
    
    NSDictionary *resultDic = [NSJSONSerialization JSONObjectWithData:[resultStr dataUsingEncoding:NSUTF8StringEncoding] options:NSJSONReadingMutableContainers error:nil];
    if (!resultDic) {
        
        completed(NO,@"请求失败");
        return ;
    }
    
    
    NSDictionary *result = [resultDic objectForKey:@"result"];
    //版本检测
#if 0
    if (temp && ![temp isKindOfClass:[NSNull class]]) {
        _isForce = [temp[@"forceUpdate"] boolValue];
        BOOL isReturn = [self checkVersion:temp[@"version"] withUpdateContent:temp[@"updateContent"]];
        //强制更新,return
        if (isReturn) return;
    }
#endif
    
    //结果验证
    NSString *statusCode = [NSString stringWithFormat:@"%@",result[@"statusCode"]];
    NSString *invoking = [NSString stringWithFormat:@"%@",result[@"invoking"]];
    if ([statusCode isEqualToString:@"success"] || [invoking isEqualToString:@"0000"]) {
        //返回成功结果
        id rs = result[@"disposeResult"];
        NSString *jsonStr = @"";
        if (rs != nil && ![rs isKindOfClass:[NSString class]] && ![result isKindOfClass:[NSNull class]]) {
            jsonStr = [self jsonStringFromJSONObject:rs];
        }
        completed(YES,jsonStr);
    }
    //账号已在另一台设备登录
    else if ([invoking integerValue] == 0002) {
        NSString *msg = result[@"message"];
        if (!_isForceLoginOut){
            [weakself loginOutWithMsg:msg];
            _isForceLoginOut = NO;
        }
    }
    else{
        NSString *msg = result[@"message"];
        if ([msg isKindOfClass:[NSNull class]]) {
            msg = @"操作失败";
        }
        completed(NO,msg);
    }
}

- (void)handleFailtureError:(NSError *)error networkParam:(NetworkParam *)networkParam currentServer:(NSString *)currentServer completed:(NetworkCompleted)completed {
    NSString *failedInfo = error.userInfo[@"NSLocalizedDescription"];
    NSLog(@"failedInfo:%@",failedInfo);
    //报错处理
    //状态栏菊花关闭
    //状态栏菊花关闭
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    if (networkParam.isSHowLoading) {
        [self.loadingView hideLoading];
    }
    if ([failedInfo isEqualToString:@"Request failed: not found (404)"]) {
        completed(NO,kREMINDER_error404);
    }else if ([failedInfo isEqualToString:@"The request timed out."] || [failedInfo isEqualToString:@"请求超时。"]){
        completed(NO,kREMINDER_timeOut);
    }else
        completed(NO,failedInfo);
}

/**
 *  拼接参数
 *
 *  @return key
 */
- (NSString *)keyWithNetworkParam:(NetworkParam *)networkParam {
    return [networkParam.methodName stringByAppendingString:networkParam.param.description];
}

/**
 *  添加公共参数
 *
 *  @return 公共参数
 */
- (NSArray *)commonParameters {
    NSMutableArray *paraters = [NSMutableArray arrayWithArray:@[@{@"user_device_type"   : [UIDevice deviceType]},
                                                                @{@"user_device_num"    : [UIDevice deviceModel]},
                                                                @{@"user_device_imei"   : [UIDevice uuid]},
                                                                @{@"user_os_version"    : [UIDevice deviceSystem]},
                                                                @{@"user_version"       : [UIDevice appVersion]},
                                                                @{@"user_reg_ip"        : [UIDevice ipAddress]},
                                                                @{@"login_longtitude"   : [UIDevice longitude]},
                                                                @{@"login_latitude"     : [UIDevice latitude]},
                                                                @{@"request_method"     : self.requestMethod}]];
    return paraters;
}

/**
 *  验签string
 *  @param dict 参数param
 *  @return <#return value description#>
 */
- (NSString *)signStringWithParam:(NSDictionary *)dict {
    NSMutableArray *keyArr = [NSMutableArray arrayWithArray:[dict allKeys]];
    //排序
    for (int first = 0; first < keyArr.count; first ++) {
        for (int index = 1; index < keyArr.count - first; index ++) {
            NSString *preStr = keyArr[index - 1];
            NSString *curStr = keyArr[index];
            if ([preStr compare:curStr] == NSOrderedDescending) {
                [keyArr replaceObjectAtIndex:index - 1 withObject:curStr];
                [keyArr replaceObjectAtIndex:index withObject:preStr];
            }
        }
    }
    //拼接字符串
    NSMutableString *signStr = [NSMutableString string];
    for (NSString *key in keyArr) {
        NSString *value = [dict objectForKey:key];
        if (([value isKindOfClass:[NSString class]] && value.length) || [value isKindOfClass:[NSNumber class]]){
            [signStr appendFormat:@"%@|",dict[key]];
        }
    }
    [signStr appendFormat:@"%@",@"WODETIdfd43"];
    return signStr;
}

#pragma mark - 版本更新
/**
 *  版本处理
 *  @param version 服务器存储的最新版本号
 */
- (BOOL)checkVersion:(NSString *)version  withUpdateContent:(NSString *)updateContent{
    if (![version isKindOfClass:[NSNull class]]) {
        if (!version.length) return NO;
        
        if ([version hasPrefix:@"v"]) {
            version = [version substringFromIndex:1];
        }
        
        if ([version floatValue] > [self.currentVersion floatValue]){
            if (_isForce){
                [self updateVersionWithIsForce:YES  withUpdateContent:updateContent];
                return YES;
            } else {
                BOOL isNotShow = [[NSUserDefaults standardUserDefaults] boolForKey:kUPDATA_firstneed];
                if (!isNotShow) {
                    [self updateVersionWithIsForce:NO  withUpdateContent:updateContent];
                    [[NSUserDefaults standardUserDefaults] setBool:YES forKey:kUPDATA_firstneed];
                }
            }
        }
    }
    return NO;
}

- (void)updateVersionWithIsForce:(BOOL)isForce  withUpdateContent:(NSString *)updateContent {
    __block NSString *contentTemp = updateContent;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        while ([[UnityTool shareInstance] showingGesturePassword] || _isForceLoginOut) {}
        dispatch_async(dispatch_get_main_queue(), ^{
            if (![contentTemp isKindOfClass:[NSString class]] || !contentTemp.length) contentTemp = @"亲，叮咚洗车有新版本了，去更新";
            WeakSelf;
            //[WDHubLoadingView hiddenHUD:kUI_Window];
            [weakself showUpdateAlert:contentTemp];
        });
    });
}

- (void)showUpdateAlert:(NSString *)contentTemp {
    //    WDAlertView *alertView = [[WDAlertView alloc] initWithTitle:@"温馨提示" message:contentTemp cancelButtonTitle:@"取消" otherButtonTitle:@"更新" clickComplete:^(WDAlertView *zcAlertView) {
    //        [[UIApplication sharedApplication] openURL:[NSURL URLWithString:@"https://itunes.apple.com/cn/app/id1071503806"]];
    //    }];
    //    alertView.showCloseButton = !_isForce;
    //    alertView.messageLabel.textAlignment = NSTextAlignmentLeft;
    //    [alertView show];
}

#pragma mark - 异地登录
/**
 *  强制下线
 */
- (void)loginOutWithMsg:(NSString *)msg {
    @weakify(self);
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
        while ([[UnityTool shareInstance] showingGesturePassword]) {}
        dispatch_async(dispatch_get_main_queue(), ^{
            DDAlertView *alert = [[DDAlertView alloc] initWithTitle:@"温馨提示" content:@"您的账号已在其他设备登录，请重新登录！" ensureButtonTitle:@"我知道了" cancelButtonTitle:nil];
            alert.clickeCompleted = ^(NSInteger index) {
                @strongify(self);
                [self loginOutUser];
            };
            [alert show];
        });
    });
}

/**
 *  确定退出
 */
- (void)loginOutUser {
    AppDelegate *app = (AppDelegate *)[UIApplication sharedApplication].delegate;
    [app setRootViewController:[DDRegAndLogController new]];
    [[NSNotificationCenter defaultCenter] postNotificationName:kNotifi_userChanged object:nil];
    _isForceLoginOut = NO;
}

#pragma mark - 工具方法

- (void)startMonitoringNetwork {
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    //开启监听
    [manager startMonitoring];
    [manager setReachabilityStatusChangeBlock:^(AFNetworkReachabilityStatus status) {
        [[NSNotificationCenter defaultCenter] postNotificationName:kNotifi_networkChange object:@(status)];
    }];
}

/**
 *  检测网络
 *  @return 是否联网
 */
- (BOOL)isConnectNetWork {
    AFNetworkReachabilityManager *manager = [AFNetworkReachabilityManager sharedManager];
    if (manager.networkReachabilityStatus == AFNetworkReachabilityStatusNotReachable){
        return NO;
    }
    return YES;
}

/**
 *  json格式数据转换成json字符串
 *  @param obj json格式数据
 *  @return json字符串
 */
- (NSString *)jsonStringFromJSONObject:(id)obj {
    if (!obj) return nil;
    if (obj == [NSNull null]) return nil;
    NSData *jsonData = [NSJSONSerialization dataWithJSONObject:obj options:NSJSONWritingPrettyPrinted error:nil];
    NSString *jsonStr = [[NSString alloc] initWithData:jsonData encoding:NSUTF8StringEncoding];
    return jsonStr;
}

/**
 *  当前使用的服务器
 *  @return 当前使用的服务器
 */
- (NSString *)getBaseURL {
    return self.currentSever;
}
/**
 *  图片路径
 *  @return 图片路径
 */
- (NSString *)getImageBaseURL {
    NSString *baseURL = [self getBaseURL];//baseUrl
    NSMutableArray *componentArr = [NSMutableArray arrayWithArray:[baseURL componentsSeparatedByString:@"/"]];
    [componentArr removeObjectAtIndex:componentArr.count - 2];
    NSString *imageBaseURL = [componentArr componentsJoinedByString:@"/"];//图片不包含LqgAppService路径
    return imageBaseURL;
}

#pragma mark - 获取网络时间

/**
 *  获取网络时间
 *  @param nowNetWorkTimeBlock 返回时间   /  或者无网络状态信息
 */
- (void)getNetworkTimeBlock:(void(^)(NSTimeInterval timestamp))nowNetWorkTimeBlock {
    NSURL *url = [NSURL URLWithString:@"http://www.baidu.com"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    _connection = [NSURLConnection connectionWithRequest:request delegate:self];
    _netWorkTimeBlock = ^(NSTimeInterval timestamp){
        if (nowNetWorkTimeBlock) {
            nowNetWorkTimeBlock(timestamp);
        }
    };
}

#pragma mark - NSURLConnectionDataDelegate

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response {
    NSHTTPURLResponse * rp = (NSHTTPURLResponse *)response;
    
    NSString *timeStr = rp.allHeaderFields[@"Date"];
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"EEE, dd MMM yyyy HH:mm:ss zzz"];
    NSLocale* local = [NSLocale currentLocale];
    [formatter setLocale:local];
    NSDate *date = [formatter dateFromString:timeStr];
    
    if (_netWorkTimeBlock) {
        _netWorkTimeBlock(date.timeIntervalSince1970);
    }
    [_connection cancel];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error {
    if (_netWorkTimeBlock) {
        _netWorkTimeBlock([NSDate date].timeIntervalSince1970);
    }
}

#pragma mark - Getter

- (DDLoadingView *)loadingView {
    if (!_loadingView) {
        _loadingView = [DDLoadingView new];
    }
    return _loadingView;
}

@end

